package thread;

import java.util.concurrent.atomic.AtomicStampedReference;


public class AtomicStampedReferenceTest {
    //获取一个初始值为【A】，初始版本为【0】的对象。
    static AtomicStampedReference<String> ref = new AtomicStampedReference<>
            ("A", 0);

    public static void main(String[] args) throws InterruptedException {
        System.out.println("main start...");
        // 获取值 A
        String prev = ref.getReference();
        // 获取版本号
        int stamp = ref.getStamp();
        System.out.println("版本："+stamp);
        // 如果中间有其它线程干扰，发生了 ABA 现象
        other();
        Thread.sleep(1000);
        // 尝试改为 C
        //这个时候，虽然旧值，还是被修改为了A，但是由于我们的【stamp】设置成了自增的，所以【它们的stamp实际上不同】，所以会更新失败。
        System.out.println("change A->C："+ref.compareAndSet(prev, "C", stamp, stamp + 1));
    }

    private static void other() throws InterruptedException {
        new Thread(() -> {
            System.out.println("change A->B："+ref.compareAndSet(ref.getReference(), "B",
                    ref.getStamp(), ref.getStamp() + 1));
            System.out.println("更新版本为："+ref.getStamp());
        }, "t1").start();

        Thread.sleep(500);

        new Thread(() -> {
            System.out.println("change B->A："+ref.compareAndSet(ref.getReference(), "A",
                    ref.getStamp(), ref.getStamp() + 1));
            System.out.println("更新版本为："+ref.getStamp());
        }, "t2").start();
    }
}
